package project.newCode.surfaces;

import project.hulpPakket.*;
import project.newCode.Hitrecord;
import project.newCode.Ray;


// Implementation is postponed to when necessary
// Proposed implementation, Point3f min, Point3f max.
public class Box extends Surface{

	public Box(Point3f pmin, Point3f pmax) {
		this.pmin = pmin;
		this.pmax = pmax;
	}

	private Point3f pmin;
	private Point3f pmax;
	@Override
	public boolean hit(Ray hittingray, double t0, double t1, Hitrecord rec) {
		Vector3f d = hittingray.getDirection();
		Vector3f vmin = Point3f.Min(pmin, hittingray.getOrigin());
		Vector3f vmax = Point3f.Min(pmax, hittingray.getOrigin());
		Vector3f tmin = new Vector3f();
		Vector3f tmax = new Vector3f();
		if(d.x >=0) {
			tmin.x = vmin.x/d.x;
			tmax.x = vmax.x/d.x;
		}
		else {
			tmin.x = vmax.x/d.x;
			tmax.x = vmin.x/d.x;
		}
		if(d.y >=0) {
			tmin.y = vmin.y/d.y;
			tmax.y = vmax.y/d.y;
		}
		else {
			tmin.y = vmax.y/d.y;
			tmax.y = vmin.y/d.y;
		}
		if(d.z >=0) {
			tmin.z = vmin.z/d.z;
			tmax.z = vmax.z/d.z;
		}
		else {
			tmin.z = vmax.z/d.z;
			tmax.z = vmin.z/d.z;
		}
		if(tmin.x > Math.min(tmax.y,tmax.z)|| tmin.y > Math.min(tmax.x, tmax.z) || tmin.z > Math.min(tmax.x, tmax.y)) {
			return false;
		}
		if(tmax.x < Math.max(tmin.y,tmin.z)|| tmax.y < Math.max(tmin.x, tmin.z) || tmax.z < Math.max(tmin.x, tmin.y)) {
			return false;
		}
		return true;
	}

	@Override
	public Box boundingbox() {
		return this;
	}

	@Override
	public Box surfaceClone() {
		return new Box(this.pmin.clone(),this.pmax.clone());
	}

	public static Box combine(Box right, Box left) {
		Point3f rpm = right.getPmin();
		Point3f lpm = left.getPmin();
		Point3f rpma = right.getPmax();
		Point3f lpma = left.getPmax();
		return new Box(new Point3f(Math.min(rpm.x, lpm.x),Math.min(rpm.y, lpm.y),Math.min(rpm.z, lpm.z)),new Point3f(Math.max(rpma.x, lpma.x),Math.max(rpma.y, lpma.y),Math.max(rpma.z, lpma.z)));
	}

	public Point3f getPmin() {
		return pmin;
	}

	public void setPmin(Point3f pmin) {
		this.pmin = pmin;
	}

	public Point3f getPmax() {
		return pmax;
	}

	public void setPmax(Point3f pmax) {
		this.pmax = pmax;
	}
	@Override
	public String toString() {
		return pmin.x+" "+ pmin.y+" "+ pmin.z+" "+ pmax.x+" "+ pmax.y+" "+ pmax.z;
	}

}
